from ninja import Router
from django.db import transaction
from django.contrib.auth import authenticate
from django.shortcuts import render

from .models import ChatUser, ChatGroup, ChatMessage, UserToGroup
from extends.http.resp import FailResp
from extends.model.auth import AuthBearer, create_jwt_token
from common.sql import RowSql
from .schemas import (
    CreateUserSchema,
    UserSchemaResp,
    CreateGroupSchema,
    GroupSchemaResp,
    CreateMessageSchema,
    MessageSchemaResp,
    CreateUserToGroupSchema,
    UserToGroupSchemaResp,
    LoginSchema,
    UserCreateMessageSchema,
)


from typing import List

user_router = Router()
group_router = Router()
message_router = Router()
chat_router = Router()


jwt_auth = AuthBearer()



########
### user
########

@user_router.post("/", response=UserSchemaResp, description="创建用户")
def create_user(request, request_body: CreateUserSchema):
    data = request_body.dict()
    user = ChatUser.objects.create_user(**data)
    return user


@user_router.post("/token", description="登录")
def create_token(request, request_body: LoginSchema):
    if user := authenticate(
        request, username=request_body.username, password=request_body.password
    ):
        token = create_jwt_token(user.id)
        return {"token": token}
    else:
        raise FailResp("用户名或密码错误")


@user_router.get(
    "/", response=List[UserSchemaResp], description="获取用户列表", auth=jwt_auth
)
def list_users(request):
    users = ChatUser.objects.all()
    return users


@user_router.get("/{user_id}", description="获取用户详情")
def user_details(request, user_id: int):
    user = ChatUser.objects.get(id=user_id)
    return {"username": user.username, "phone": user.phone}


@user_router.post("/create_group/{user_id}", description="用户创建群组")
def user_create_group(request, user_id: int, request_body: CreateGroupSchema):
    data = request_body.dict()
    with transaction.atomic():
        group = ChatGroup.objects.create(**data)
        UserToGroup.objects.create(user_id=user_id, group_id=group.id)
    return {"msg": "ok", "code": 201}


@user_router.get(
    "/groups/{user_id}",
    response=List[GroupSchemaResp],
    description="查询用户加入的群组",
)
def get_user_to_groups(request, user_id: int):
    """多对多查询使用原生sql查询语句"""
    # 实例化并校验
    row_sql = RowSql(fields=GroupSchemaResp.Meta.fields, table="chat_group")

    # sql语句编写
    sql_select = f"select {row_sql.get_sql_fiels_names()} from chat_group"
    sql_join = "left join user_to_group on chat_group.id = user_to_group.group_id"
    sql_where = "where user_to_group.user_id = %s"

    # 执行原生sql语句
    groups_list = row_sql.execute_sql(
        (
            sql_select,
            sql_join,
            sql_where,
        ),
        (user_id,),
    )
    return groups_list


@user_router.get(
    "/messages",
    response=List[MessageSchemaResp],
    description="查询用户在当前群组发送的消息",
)
def get_user_messages(request, user_id: int, group_id: int):
    messages = ChatMessage.objects.filter(user_id=user_id, group_id=group_id)
    return messages


#########
### group
#########

@group_router.get("/", response=List[GroupSchemaResp], description="查询群组列表")
def list_groups(request):
    groups = ChatGroup.objects.all()
    return groups


@group_router.post("/", response=GroupSchemaResp, description="创建群组")
def create_group(request, request_body: CreateGroupSchema):
    data = request_body.dict()
    if ChatUser.objects.filter(id=request_body.leader).exists() == False:
        raise FailResp("用户不存在")
    group = ChatGroup.objects.create(**data)
    return group


@group_router.post(
    "/create_user_to_group",
    response=UserToGroupSchemaResp,
    description="创建用户到群组关系",
)
def create_user_to_group(request, request_body: CreateUserToGroupSchema):
    data = request_body.dict()
    if ChatUser.objects.filter(id=data["user_id"]).exists() == False:
        raise FailResp("用户不存在")
    if ChatGroup.objects.filter(id=data["group_id"]).exists() == False:
        raise FailResp("群组不存在")

    if UserToGroup.objects.filter(
        user_id=data["user_id"], group_id=data["group_id"]
    ).exists():
        raise FailResp("用户已经加入群组")

    user_to_group = UserToGroup.objects.create(**data)
    return user_to_group


###########
### message
###########


@message_router.post("/", response=MessageSchemaResp, description="创建消息", auth=jwt_auth)
def create_message(request, request_body: CreateMessageSchema):
    data = request_body.dict()
    if ChatUser.objects.filter(id=data["user_id"]).exists() == False:
        raise FailResp("用户不存在")
    if ChatGroup.objects.filter(id=data["group_id"]).exists() == False:
        raise FailResp("群组不存在")
    message = ChatMessage.objects.create(**data)
    return message


@message_router.get("/", response=List[MessageSchemaResp], description="查询消息列表")
def list_messages(request):
    messages = ChatMessage.objects.all()
    return messages


##########
### chat
##########

@chat_router.get("/")
def get_chat_html(request, group_id: int, user_id: int):
    group = ChatGroup.objects.get(id=group_id)
    user = ChatUser.objects.get(id=user_id)
    return render(request, "chat/chat.html", {"group": group, "user": user})